package com.seleniti.enpareja.controller.model.integration.database.domain;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.jdo.annotations.Column;
import javax.jdo.annotations.Element;
import javax.jdo.annotations.Extension;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.Order;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import javax.jdo.annotations.Version;
import javax.jdo.annotations.VersionStrategy;
import javax.validation.constraints.NotNull;

import com.google.appengine.datanucleus.annotations.Unowned;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
@Version(column = "version", strategy = VersionStrategy.VERSION_NUMBER, extensions = { @Extension(vendorName = "datanucleus", key = "field-name", value = "version") })
public class Couple implements Serializable {
	/**
	 * Serial no.
	 */
	private static final long serialVersionUID = -2032844705499847388L;

	@PrimaryKey
	@Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
	@Extension(vendorName = "datanucleus", key = "gae.encoded-pk", value = "true")
	private String coupleId;

	@Column(allowsNull = "false")
	@NotNull
	@Unowned
	private User member1;

	@Column(allowsNull = "false")
	@NotNull
	@Unowned
	private User member2;
	
	@Column(allowsNull = "false")
	@NotNull
	private CoupleType coupleType;

	@Persistent(defaultFetchGroup = "true")
	private Garage garage;

	@Persistent(mappedBy = "couple")
	@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "text asc"))
	@Element(dependent = "true")
	private List<ShoppingListElement> shoppingListElements = new ArrayList<>(0);

	@Persistent(mappedBy = "couple")
	@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "text asc"))
	@Element(dependent = "true")
	private List<HomeTask> homeTasks = new ArrayList<>(0);

	@Persistent(mappedBy = "couple")
	@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "date asc"))
	@Element(dependent = "true")
	private List<Food> foods = new ArrayList<>(0);

	@Persistent(mappedBy = "couple")
	@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "date asc, savedAt asc"))
	@Element(dependent = "true")
	private List<SharedExpense> sharedExpenses = new ArrayList<>(0);

	@Persistent(mappedBy = "couple")
	@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "date asc"))
	@Element(dependent = "true")
	private List<WorkShift> workShits = new ArrayList<>(0);

	@Persistent(mappedBy = "couple")
	@Order(extensions = @Extension(vendorName = "datanucleus", key = "list-ordering", value = "name asc"))
	@Element(dependent = "true")
	private List<Store> pendingAtStore = new ArrayList<>(0);

	protected long version;

	public Couple() {
		// Default const.
	}
	
	public User getMember1() {
		return member1;
	}

	public void setMember1(User member1) {
		this.member1 = member1;
	}

	public User getMember2() {
		return member2;
	}

	public void setMember2(User member2) {
		this.member2 = member2;
	}

	public Garage getGarage() {
		return garage;
	}

	public void setGarage(Garage garage) {
		this.garage = garage;
	}

	public String getCoupleId() {
		return coupleId;
	}

	public void setCoupleId(String coupleId) {
		this.coupleId = coupleId;
	}

	public List<ShoppingListElement> getShoppingListElements() {
		return shoppingListElements;
	}

	public void setShoppingListElements(List<ShoppingListElement> shoppingListElements) {
		this.shoppingListElements = shoppingListElements;
	}

	@Override
	public String toString() {
		return "Couple [coupleId=" + coupleId + ", member1=" + member1 + ", member2=" + member2 + ", garage=" + garage
		/*
		 * + ", shoppingListElements=" + shoppingListElements + ", homeTasks=" +
		 * homeTasks
		 */
		+ ", version=" + version + "]";
	}

	public List<HomeTask> getHomeTasks() {
		return homeTasks;
	}

	public void setHomeTasks(List<HomeTask> homeTasks) {
		this.homeTasks = homeTasks;
	}

	public List<Food> getFoods() {
		return foods;
	}

	public void setFoods(List<Food> foods) {
		this.foods = foods;
	}

	public List<SharedExpense> getSharedExpenses() {
		return sharedExpenses;
	}

	public void setSharedExpenses(List<SharedExpense> sharedExpenses) {
		this.sharedExpenses = sharedExpenses;
	}

	public List<WorkShift> getWorkShits() {
		return workShits;
	}

	public void setWorkShits(List<WorkShift> workShits) {
		this.workShits = workShits;
	}

	public List<Store> getPendingAtStore() {
		return pendingAtStore;
	}

	public void setPendingAtStore(List<Store> pendingAtStore) {
		this.pendingAtStore = pendingAtStore;
	}

	public int getPendingShoppingListElements() {
		if (this.getShoppingListElements() != null) {
			int pending = 0;
			for (ShoppingListElement element : this.getShoppingListElements()) {
				if (element != null && !element.isWeHave()) {
					pending++;
				}
			}

			return pending;
		} else {
			return 0;
		}
	}

	public int getPendingHomeTasks() {
		if (this.getHomeTasks() != null) {
			int pending = 0;
			for (HomeTask element : this.getHomeTasks()) {
				if (element != null && element.getLastTime() == null) {
					pending++;
				}
			}

			return pending;
		} else {
			return 0;
		}
	}

	public int getPendingProducts() {
		if (this.getPendingAtStore() != null) {
			int pending = 0;
			for (Store store : this.getPendingAtStore()) {
				if (store != null && store.getProducts() != null) {
					for (Product p : store.getProducts()) {
						if (p != null && p.isPending()) {
							pending++;
						}
					}
				}
			}

			return pending;
		} else {
			return 0;
		}
	}

	public CoupleType getCoupleType() {
		return coupleType;
	}

	public void setCoupleType(CoupleType coupleType) {
		this.coupleType = coupleType;
	}

}
